package com.why.util;

import com.why.model.MsgModel;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * excel 处理工具类
 */
public class ExcelUtils {

    public static void main(String[] args) {
//        readExcel("C:\\tmp\\test.xls");
        readExcel("C:\\tmp\\request.xlsx");
    }

    public static List<MsgModel> readExcel(String path) {
        try {
            if (path.endsWith(".xls")) {
                return readXLSExcel(path);
            } else if (path.endsWith(".xlsx")) {
                return readXLSXExcel(path);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("读取excel异常 ");
        }
        return new ArrayList<>();
    }

    /**
     * 读取xls文件
     *
     * @param path 文件路径
     */
    private static List<MsgModel> readXLSExcel(String path) throws IOException {
        List<MsgModel> msgModelList = new ArrayList<>();
        HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(new File(path)));
        HSSFSheet sheet;
        for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {//获取每个Sheet表
            MsgModel msgModel = new MsgModel();
            sheet = workbook.getSheetAt(sheetIndex);
            if (sheet.getPhysicalNumberOfRows() == 0) {
                continue;
            }
            getParamInfo(sheet, msgModel, 0, false);
//            for (int rowIndex = 0; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {//获取每行
//                HSSFRow row = sheet.getRow(rowIndex);
//                try {
//                    getParamInfo(rowIndex, row, msgModel);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
            System.out.println("---Sheet表" + sheetIndex + "处理完毕---");
            System.out.println(msgModel.toString());
            msgModelList.add(msgModel);
        }
        return msgModelList;
    }

    /**
     * 读取xlsx文件
     *
     * @param path 文件路径
     */
    private static List<MsgModel> readXLSXExcel(String path) throws IOException {
        List<MsgModel> msgModelList = new ArrayList<>();
        XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(path)));
        XSSFSheet sheet;
        for (int sheetIndex = 0; sheetIndex < workbook.getNumberOfSheets(); sheetIndex++) {//获取每个Sheet表
            MsgModel msgModel = new MsgModel();
            sheet = workbook.getSheetAt(sheetIndex);
            if (sheet.getPhysicalNumberOfRows() == 0) {
                continue;
            }
            getParamInfo(sheet, msgModel, 0, false);
//            for (int rowIndex = 0; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {//获取每行
//                XSSFRow row = sheet.getRow(rowIndex);
//                try {
//                    getParamInfo(rowIndex, row, msgModel);
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
            System.out.println("---Sheet表" + sheetIndex + "处理完毕---");
            System.out.println(msgModel.toString());
            msgModelList.add(msgModel);
        }
        return msgModelList;
    }

    /**
     * 获取excel中的信息，不包含子类
     */
    private static void getParamInfo(int rowIndex, HSSFRow row, MsgModel msgModel) {
        MsgModel.OriginParamModel paramModel = new MsgModel.OriginParamModel();
        // 第一行 消息整体信息
        if (rowIndex == 0) {
            for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                HSSFCell cell = row.getCell(k);
                if (cell == null) {
                    continue;
                }
                if (k == 0) {
                    if (StringUtil.isEmpty(cell.toString())) {
                        throw new RuntimeException("class name is null");
                    }
                    msgModel.setMsgName(cell.toString());
                } else if (k == 1) {
                    msgModel.setMsgDesc(StringUtil.isEmpty(cell.toString()) ? "" : cell.toString());
                } else if (!StringUtil.isEmpty(cell.toString())) {
                    msgModel.addVersions(cell.toString());
                }
            }
            // 跳过表头
        } else if (rowIndex > 1) {
            for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                HSSFCell cell = row.getCell(k);
                if (cell == null || StringUtil.isEmpty(cell.toString())) {
                    continue;
                }
                assembleParamModel(k, paramModel, cell.toString());
            }
            msgModel.addParamModels(paramModel);
        }
    }

    /**
     * 获取excel中的信息，不包含子类
     */
    private static void getParamInfo(int rowIndex, XSSFRow row, MsgModel msgModel) {
        MsgModel.OriginParamModel paramModel = new MsgModel.OriginParamModel();
        // 第一行 消息整体信息
        if (rowIndex == 0) {
            for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                XSSFCell cell = row.getCell(k);
                if (cell == null) {
                    continue;
                }
                if (k == 0) {
                    if (StringUtil.isEmpty(cell.toString())) {
                        throw new RuntimeException("class name is null");
                    }
                    msgModel.setMsgName(cell.toString());
                } else if (k == 1) {
                    msgModel.setMsgDesc(StringUtil.isEmpty(cell.toString()) ? "" : cell.toString());
                } else if (!StringUtil.isEmpty(cell.toString())) {
                    msgModel.addVersions(cell.toString());
                }
            }
            // 跳过表头
        } else if (rowIndex > 1) {
            for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                XSSFCell cell = row.getCell(k);
                if (cell == null || StringUtil.isEmpty(cell.toString())) {
                    continue;
                }
                assembleParamModel(k, paramModel, cell.toString());
            }
            msgModel.addParamModels(paramModel);
        }
    }

    /**
     * 获取excel中的信息，包含子类
     */
    private static void getParamInfo(XSSFSheet sheet, MsgModel msgModel, int rowIndex, boolean innerClassFlag) {
        XSSFRow row = sheet.getRow(rowIndex);
        if (row == null) {
            return;
        }
        try {
            MsgModel.OriginParamModel paramModel = new MsgModel.OriginParamModel();
            // 第一行 消息整体信息
            if (rowIndex == 0 || innerClassFlag) {
                for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                    XSSFCell cell = row.getCell(k);
                    if (cell == null) {
                        continue;
                    }
                    if (k == 0) {
                        if (StringUtil.isEmpty(cell.toString())) {
                            throw new RuntimeException("class name is null");
                        }
                        msgModel.setMsgName(cell.toString());
                    } else if (k == 1) {
                        msgModel.setMsgDesc(StringUtil.isEmpty(cell.toString()) ? "" : cell.toString());
                    } else if (!StringUtil.isEmpty(cell.toString())) {
                        msgModel.addVersions(cell.toString());
                    }
                }
                // 跳过表头
            } else if (rowIndex > 1) {
                for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                    XSSFCell cell = row.getCell(k);
                    if (cell == null || StringUtil.isEmpty(cell.toString())) {
                        continue;
                    }
                    // >> 代表子类
                    if (">>".equals(cell.toString())) {
                        MsgModel childMsgModel = new MsgModel();
                        msgModel.setChildModel(childMsgModel);
                        getParamInfo(sheet, childMsgModel, ++rowIndex, true);
                        return;
                    }
                    assembleParamModel(k, paramModel, cell.toString());
                }
                msgModel.addParamModels(paramModel);
            }
            getParamInfo(sheet, msgModel, ++rowIndex, false);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取excel中的信息，包含子类
     */
    private static void getParamInfo(HSSFSheet sheet, MsgModel msgModel, int rowIndex, boolean innerClassFlag) {
        HSSFRow row = sheet.getRow(rowIndex);
        if (row == null) {
            return;
        }
        try {
            MsgModel.OriginParamModel paramModel = new MsgModel.OriginParamModel();
            // 第一行 消息整体信息
            if (rowIndex == 0 || innerClassFlag) {
                for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                    HSSFCell cell = row.getCell(k);
                    if (cell == null) {
                        continue;
                    }
                    if (k == 0) {
                        if (StringUtil.isEmpty(cell.toString())) {
                            throw new RuntimeException("class name is null");
                        }
                        msgModel.setMsgName(cell.toString());
                    } else if (k == 1) {
                        msgModel.setMsgDesc(StringUtil.isEmpty(cell.toString()) ? "" : cell.toString());
                    } else if (!StringUtil.isEmpty(cell.toString())) {
                        msgModel.addVersions(cell.toString());
                    }
                }
                // 跳过表头
            } else if (rowIndex > 1) {
                for (int k = 0; k <= row.getPhysicalNumberOfCells(); k++) {//获取每个单元格
                    HSSFCell cell = row.getCell(k);
                    if (cell == null || StringUtil.isEmpty(cell.toString())) {
                        continue;
                    }
                    // >> 代表子类
                    if (">>".equals(cell.toString())) {
                        MsgModel childMsgModel = new MsgModel();
                        msgModel.setChildModel(childMsgModel);
                        getParamInfo(sheet, childMsgModel, ++rowIndex, true);
                        return;
                    }
                    assembleParamModel(k, paramModel, cell.toString());
                }
                msgModel.addParamModels(paramModel);
            }
            getParamInfo(sheet, msgModel, ++rowIndex, false);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private static void assembleParamModel(int index, MsgModel.OriginParamModel paramModel, String value) {
        switch (index) {
            case 0:
                paramModel.setParamName(value);
                break;
            case 1:
                paramModel.setOutParamName(value);
                break;
            case 2:
                paramModel.setParamDesc(value);
                break;
            case 3:
                paramModel.setOutParamType(value);
                break;
            case 4:
                paramModel.setMsgParamType(value);
                break;
            case 5:
                paramModel.setParamCharType(value);
                break;
            case 6:
                String lengthStr = value;
                if (lengthStr.contains(".")) {
                    lengthStr = lengthStr.substring(0, lengthStr.indexOf("."));
                }
                paramModel.setCharLength(lengthStr);
                break;
            case 7:
                paramModel.setDefaultValue(value);
                break;
            case 8:
                paramModel.setVersion(StringUtil.isEmpty(value) ? "ALL" : value);
                break;
            default:
                // do nothing
        }
    }
}
